import Foundation

/// Primitive views have a `Body` type of `Never` and have custom logic for
/// building and updating nodes created for them in the view graph.
///
/// Primitive views have complete control of how they build and update nodes. Note that a view is
/// a description of how to create a **list** of controls. There are various types of primitive
/// views:
///
/// * Ones that manage a single control, or that let a user specify a collection of other views.
///
/// * Ones that work as modifiers, changing the controls that an underlying view generates
///   individually. Those primitive views additionally conform to the `ModifierView` protocol.
///
/// * Ones that define a container for the controls generated by the underlying view. They can
///   load the controls lazily. Those primitive views additionally conform to the `LayoutRootView`
///   protocol.
protocol PrimitiveView: GenericView {}

extension PrimitiveView {
    public var body: Never { fatalError("Cannot evaluate body of primitive view") }
}

extension View {
    static var size: Int? {
        if let I = Self.self as? PrimitiveView.Type {
            return I.size
        }
        return Body.size
    }
}

extension View {
    var view: GenericView {
        if let primitiveView = self as? PrimitiveView {
            return primitiveView
        }
        return ComposedView(view: self)
    }
}
